package com.hzmall.common;

import com.hzmall.util.PropertiesUtil;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;

import java.util.*;

public class RedisShardedPool {
    private static ShardedJedisPool pool;
    private static Integer maxTotal = PropertiesUtil.getIntegerPropertyWithDefault("redis.max.total",20);
    private static Integer maxIdle = PropertiesUtil.getIntegerPropertyWithDefault("redis.max.idle",10);
    private static Integer minIdle = PropertiesUtil.getIntegerPropertyWithDefault("redis.min.idle",2);
    private static Boolean testOnBorrow = PropertiesUtil.getBooleanProperty("redis.test.borrow");
    private static Boolean testOnReturn = PropertiesUtil.getBooleanProperty("redis.test.return");
    private static Map<String, String> ipMap;
    private static Integer redisCount = PropertiesUtil.getIntegerProperty("redis.count");
    private static List<JedisShardInfo> infoList = new ArrayList<JedisShardInfo>();

    static {
        getIpPortMap();
        init();
    }
    private static void getIpPortMap(){
        ipMap = new IdentityHashMap<String, String>();
        for (int i=1;i<=redisCount;i++){
            String ip = PropertiesUtil.getStringProperty("redis"+i+".ip");
            String port = String.valueOf(PropertiesUtil.getIntegerProperty("redis"+i+".port"));
            ipMap.put(ip, port);
        }
    }

    private static void init(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMinIdle(minIdle);
        config.setTestOnReturn(testOnReturn);
        config.setTestOnBorrow(testOnBorrow);
        config.setMaxIdle(maxIdle);
        config.setMaxTotal(maxTotal);
        config.setBlockWhenExhausted(true);
        Iterator iterator = ipMap.entrySet().iterator();
        JedisShardInfo info = null;
        infoList.clear();
        while (iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            String ip = (String) entry.getKey();
            String port = (String) entry.getValue();
            info = new JedisShardInfo(ip, Integer.parseInt(port));
            infoList.add(info);
        }
        pool = new ShardedJedisPool(config,infoList, Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN);
    }
    public static ShardedJedis getJedis(){
        return pool.getResource();
    }
    public static void returnResource(ShardedJedis jedis){
        pool.returnResource(jedis);
    }
    public static void returnBrokenResource(ShardedJedis jedis){
        pool.returnBrokenResource(jedis);
    }
}
